/*
 * Alloy Analyzer
 * Copyright (c) 2002 Massachusetts Institute of Technology
 *
 * The Alloy Analyzer is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * The Alloy Analyzer is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with the Alloy Analyzer; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
package alloy.ast;

import java.util.Iterator;

/**
 * Represents the id (name) of a Module.  Supports the notion 
 * of parameterized name (for polymorphic modules).
 **/
public class ModuleId extends Id {
	
    /**
     * type parameters index
     */
    private static final int TYPE_PARAMS_INDEX = 0;
	
    public ModuleId(Location location_, String name_, QualifiedNames typeParams_) {
	super (location_, name_);
	addChild(typeParams_);
    }
    
    public ModuleId(String name_, QualifiedNames typeParams_) {
	super (name_);
	addChild(typeParams_);
    }
    
    /**
     * gets the type parameters of this
     * @return the {@link QualifiedNames}
	 */
    public QualifiedNames getTypeParams() {
	return (QualifiedNames)childAt(TYPE_PARAMS_INDEX);
    }
    
    /**
     * sets the type parameters of this
     */
    public void setTypeParams(QualifiedNames newTypeParams_) {
	setChild(TYPE_PARAMS_INDEX, newTypeParams_);	
    }
	
    /**
     * @return true if this has no type parameters
     */
    public boolean hasNoTypeParams() {
	return (getTypeParams().numChildren() == 0);	
    }
    /**
     * @param obj the object for comparison
     * @return <pre>true</pre> if this name is the same as obj; <pre>false</pre> otherwise
     */
    public boolean equals(Object obj) {
	if (super.equals(obj) && (obj instanceof ModuleId)) {
	    ModuleId other = (ModuleId) obj;
	    if (getTypeParams().numChildren() == other.getTypeParams().numChildren()) {
		
		Iterator i = getTypeParams().getQualifiedNameIter();
		Iterator j = other.getTypeParams().getQualifiedNameIter();
		
		// iterate and compare
		while (i.hasNext()) {
		    if (!i.next().equals(j.next())) {
			return false;
		    }
		}
		return true;
		
	    }
	}
	return false;
    }

    public String unparameterizedNodeString() {
	return super.nodeString();
    }

    public String toString() {
	return nodeString();
    }

    public String nodeString() {
	if (hasNoTypeParams()) {
	    return super.nodeString();
	} else {
	    StringBuffer typeParamsString = new StringBuffer(super.nodeString());
	    typeParamsString.append("[");

	    for (Iterator i = getTypeParams().getQualifiedNameIter(); i.hasNext();) {
		typeParamsString.append(((QualifiedName)i.next()).nodeString());
		if (i.hasNext()) {
		    typeParamsString.append(",");
		}
	    }
	    
	    typeParamsString.append("]");
	    
	    return typeParamsString.toString();
	}
    }
}

